package com.ws.utils.xmlUtil;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * @author
 * 
 *         更改所生成类型注释的模板为 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
public class DcUtilFreeMarker {

	public static Map<Object, Object> cachedTemplates = new HashMap<Object, Object>();

	private static Template getTemplateFromCache(String location) throws IOException, TemplateException {
		return getTemplateFromCache(new URL(location));
	}

	private static Template getTemplateFromCache(URL locationUrl) throws IOException, TemplateException {
		Template template = (Template) cachedTemplates.get(locationUrl);
		//if (template == null) {
			synchronized (DcUtilFreeMarker.class) {
				template = (Template) cachedTemplates.get(locationUrl);
				if (template == null) {
					Reader locationReader = new InputStreamReader(locationUrl.openStream(),"UTF-8");
					Configuration config = makeDefaultConfig();
					String locationString = locationUrl.getPath();
					template = new Template(locationString, locationReader, config);

					cachedTemplates.put(locationUrl, template);
				}
			}
		//}
		template.setEncoding("UTF-8");
		return template;
	}

	private static Configuration defaultConfig = null;

	// private static Configuration makeDefaultConfig() throws TemplateException
	// {
	// Configuration config = Configuration.getDefaultConfiguration();
	// config.setObjectWrapper(BeansWrapper.getDefaultInstance());
	// config.setSetting("datetime_format", "yyyy-MM-dd HH:mm:ss.SSS");
	// return config;
	// }
	public static Configuration makeDefaultConfig() throws TemplateException {
		synchronized (DcUtilFreeMarker.class) {
			if (defaultConfig == null) {
				Configuration config = new Configuration();
				config.setObjectWrapper(BeansWrapper.getDefaultInstance());
				config.setSetting("datetime_format", "yyyy-MM-dd HH:mm:ss.SSS");
				config.setCacheStorage(new DcFtlCacheStorage("ftl"));
				defaultConfig = config;
			}
		}
		defaultConfig.setDefaultEncoding("UTF-8");
		defaultConfig.setLocale(Locale.CHINA);
		return defaultConfig;
	}

	/**
	 * 模板替换
	 * 
	 * @param str
	 *            模板的字符串
	 * @param context
	 *            数据
	 * @return 替换好的字符串
	 * @throws TemplateException
	 * @throws IOException
	 */
	public static String processTemplate(String str, Object context) throws TemplateException, IOException {
		return renderTemplate(String.valueOf(str.hashCode()), str, context);

		// StringWriter strWriter = new StringWriter();
		// Reader reader = new StringReader(str);
		// Template template = new Template("",reader);
		// template.process(context,strWriter);
		// return strWriter.toString();
	}

	public static String renderTemplate(String templateIdString, String template, Object context)
			throws TemplateException, IOException {
		StringWriter outWriter = new StringWriter();
		if (context == null) {
			context = new HashMap();
		}

		Reader templateReader = new StringReader(template);
		renderTemplate(templateIdString, templateReader, context, outWriter);
		return outWriter.toString();
	}

	public static void renderTemplate(String templateIdString, Reader templateReader, Object context, Writer outWriter)
			throws TemplateException, IOException {
		if (context == null) {
			context = new HashMap();
		}

		Configuration config = makeDefaultConfig();
		Template template = new Template(templateIdString, templateReader, config);

		template.process(context, outWriter);
	}

	/**
	 * @param location
	 * @param context
	 * @param writer
	 */
	public static void processTemplate(String location, Object context, Writer outWriter) throws MalformedURLException,
            TemplateException, IOException {
		Template template = (Template) getTemplateFromCache(location);
		if (context == null) {
			context = new HashMap();
		}
		template.process(context, outWriter);
	}

	/**
	 * @param location
	 * @param context
	 * @param outWriter
	 * @throws MalformedURLException
	 * @throws TemplateException
	 * @throws IOException
	 */
	public static void processTemplate(URL location, Object context, Writer outWriter) throws MalformedURLException,
            TemplateException, IOException {
		Template template = (Template) getTemplateFromCache(location);
		if (context == null) {
			context = new HashMap();
		}
		template.process(context, outWriter);
	}

	/**
	 * @param location
	 * @param context
	 * @return
	 * @throws MalformedURLException
	 * @throws TemplateException
	 * @throws IOException
	 */
	public static String processTemplate(URL location, Object context) throws MalformedURLException, TemplateException,
			IOException {
		StringWriter writer = new StringWriter();
		processTemplate(location, context, writer);
		return writer.toString();
	}
}
